﻿using System;
using System.Drawing;
using System.Globalization;
using System.Management.Automation;
using System.Runtime.InteropServices;
using BGShell.Interop;
using BGShell.Drawing;
using BGShell.PowerShell.Interop;

namespace BGShell.PowerShell.DataTips
{
    internal sealed class CommandInfoDataTip : PSObjectDataTip
    {
        private CommandInfo _resolved;

        private String _valueAsString;
        private Icon _icon;

        public CommandInfoDataTip(String name, CommandInfo value)
            : base(name, value, false, typeof(CommandInfo))
        {
            _resolved = value;
            
            var alias = value as AliasInfo;
            if (alias != null)
            {
                _resolved = alias.ResolvedCommand;
            }

            var app = _resolved as ApplicationInfo;
            
            if (app != null)
            {
                GetFileTypeAndIcon(app, out _valueAsString, out _icon);
            }
            else
            {
                _valueAsString = GetCommandType(_resolved);
            }

            if (alias != null)
            {
                _valueAsString = "alias (" + _valueAsString + ")";
            }
        }

        public CommandInfoDataTip(CommandInfo command)
            : this(GetCommandType(command), command)
        {
        }

        public CommandInfo CommandInfo
        {
            get { return (CommandInfo)(Value); }
        }

        public override bool HasIcon
        {
            get { return true; }
        }

        public override string Name
        {
            get { return CommandInfo.Name; }
            set { }
        }

        public override string ValueAsString
        {
            get { return _valueAsString; }
        }

        public override void PaintIcon(Graphics graphics, Rectangle rect)
        {
            if (_icon == null)
            {
                base.PaintIcon(graphics, rect);
            }
            else
            {
                graphics.DrawIcon(_icon, rect);
            }

            if (IsAlias)
            {
                TypeModelIconRenderer.RenderIcon(graphics, rect, TypeModelIcon.OverlayAlias, TypeModelIconOverlay.None);
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_icon != null)
                {
                    _icon.Dispose();
                }
            }

            base.Dispose(disposing);
        }

        private bool IsAlias
        {
            get { return _resolved != CommandInfo; }
        }

        private static void GetFileTypeAndIcon(ApplicationInfo app, out String description, out Icon icon)
        {
            const int FILE_ATTRIBUTE_NORMAL = 0x00000080;

            var attributes = FILE_ATTRIBUTE_NORMAL;

            var flags = SHGetFileInfoFlags.Icon |
                        SHGetFileInfoFlags.SmallIcon |
                        SHGetFileInfoFlags.TypeName;

            var info = SHFILEINFO.GetFileInfo(app.Path, attributes, flags);

            description = info.szTypeName;
            
            if (info.hIcon == IntPtr.Zero)
            {
                icon = null;
            }
            else
            {
                icon = System.Drawing.Icon.FromHandle(info.hIcon);
            }
        }

        private static string GetCommandType(CommandInfo command)
        {
            return Enum.GetName(typeof(CommandTypes), command.CommandType).ToLower(CultureInfo.CurrentUICulture);
        }
    }
}